import datetime
import re

from django import forms
from django.contrib import messages
from django.db import connection
from django.forms import fields, widgets
from django.shortcuts import HttpResponse, redirect, render
from django.utils import timezone

from object_found import models
from object_found import wechatpost as wp


def date2str(date):
    return date.strftime('%Y%m%d')


def str2date(str):
    return str[:4] + "-" + str[4:6] + "-" + str[6:]


class NewObjectForm(forms.Form):
    name = fields.CharField(label='物品名称',
                            max_length=100,
                            min_length=1,
                            error_messages={
                                "required": '不能为空',
                                "max_length": "名称不能超过100个字符",
                                "min_length": "必须填写名称"
                            })
    place = fields.CharField(label='物品位置',
                             max_length=100,
                             min_length=1,
                             error_messages={
                                 "required": '不能为空',
                                 "max_length": "位置不能超过100个字符",
                                 "min_length": "必须填写位置"
                             })
    type = fields.ChoiceField(
        label="物品类型",
        choices=[(1, "食品/药品"), (2, "日用消耗品"), (3, "工具/非消耗品"),
                 (4, "其他物品")],  #单选下拉框
        initial=1)
    count = fields.IntegerField(label="物品数量", min_value=1, initial=1)
    unit = fields.ChoiceField(
        label="单位",
        choices=[(1, "个"), (2, "台"), (3, "箱"), (4, "袋"), (5, "瓶"), (6, "盒"),
                 (7, "件"), (8, "其他")],  #单选下拉框
        initial=1)
    valid = fields.CharField(label='指定日期',
                             required=False,
                             max_length=8,
                             min_length=8)
    spec_days = fields.IntegerField(label_suffix="天",
                                    min_value=0,
                                    required=False)
    spec_weeks = fields.IntegerField(label_suffix="周",
                                     min_value=0,
                                     required=False)
    spec_months = fields.IntegerField(label_suffix="月",
                                      min_value=0,
                                      required=False)
    forever = fields.ChoiceField(label='不过期',
                                 widget=widgets.CheckboxInput(),
                                 required=False)
    note = fields.CharField(label='备注', required=False)

    def set_default(self, name, place, type, count, unit, valid, note):
        self.fields['name'].initial = name
        self.fields['place'].initial = place
        self.fields['type'].initial = type
        self.fields['count'].initial = count
        self.fields['unit'].initial = unit
        self.fields['valid'].initial = valid
        self.fields['note'].initial = note


KEY_WORDS_INDEX = ["数量", "有效期", "保质期"]
KEY_WORDS_OPERATOR = {"大于": 1, "多于": 1, ">": 1, "小于": 2, "少于": 2, "<": 2}
KEY_WORDS_UNIT = {"天": 1, "周": 7, "月": 30}


def find_key_words(note):
    operator = None
    value = None
    days = None
    for key in KEY_WORDS_OPERATOR:
        if key in note:
            operator = KEY_WORDS_OPERATOR[key]
            break
    match = re.search('\d+', note)
    if match:
        value = int(match.group())
    for key in KEY_WORDS_UNIT:
        if key in note:
            days = KEY_WORDS_UNIT[key]
            break
    return operator, value, days


def check_if_warning(count, valid_date, note):
    operator, value, days = find_key_words(note)
    if note.find("有效期") >= 0 or note.find("保质期") >= 0:
        date = timezone.now()
        if operator == 1:
            return (date +
                    datetime.timedelta(days=days * value)).date() < valid_date
        if operator == 2:
            return (date +
                    datetime.timedelta(days=days * value)).date() > valid_date
        return None
    if note.find("数量") >= 0:
        if operator == 1:
            return count > value
        if operator == 2:
            return count < value
        return None
    return None


def query_all_dict(sql_str):
    # 获取游标对象
    cursor = connection.cursor()
    # 使用原生SQL进行查询
    cursor.execute(sql_str)
    # 获取所有的数据
    return cursor.fetchall()


# Create your views here.
def get_all_object(request):
    place_set = query_all_dict(
        "select distinct place from object_found_object_info")
    place_list = []
    selected = {
        "name": "",
        "place": "所有位置",
        "type": '0',
        "valid": '0',
        "note": ""
    }
    for item in place_set:
        place_list.append(item[0])

    if request.method == "GET":
        user_list_obj = models.object_info.objects.filter(
            data_status=0).order_by("name")

        return render(request, 'object_list.html', {
            'li': user_list_obj,
            'pls': place_list,
            'slt': selected
        })
    if request.method == 'POST':
        name = request.POST['name']
        place = request.POST['place']
        type = request.POST['type']
        valid = request.POST['valid']
        note = request.POST['note']
        condtions = {"data_status": 0}
        selected["name"] = name
        selected["place"] = place
        selected["type"] = type
        selected["valid"] = valid
        selected["note"] = note
        if name != '':
            condtions["name__contains"] = name
        if place != "所有位置":
            condtions["place"] = place
        if type != '0':
            condtions["type"] = int(type)
        if valid != '0':
            if valid == '1':
                condtions["valid_date__lt"] = timezone.now()
            if valid == '2':
                condtions["valid_date__gt"] = timezone.now()
                condtions["valid_date__lt"] = timezone.now(
                ) + datetime.timedelta(days=7)
            if valid == '3':
                condtions["valid_date__gt"] = timezone.now()
                condtions["valid_date__lt"] = timezone.now(
                ) + datetime.timedelta(days=30)
            if valid == '4':
                condtions["valid_date__lt"] = '9999-12-31'
                condtions["valid_date__gt"] = timezone.now(
                ) + datetime.timedelta(days=30)
            if valid == '5':
                condtions["valid_date"] = '9999-12-31'
        if note != '':
            condtions["note__contains"] = note

        user_list_obj = models.object_info.objects.filter(
            **condtions).order_by("valid_date")
        return render(request, 'object_list.html', {
            'li': user_list_obj,
            'pls': place_list,
            'slt': selected
        })


def warning_objects(request):
    place_set = query_all_dict(
        "select distinct place from object_found_object_info")
    place_list = []
    selected = {
        "name": "",
        "place": "所有位置",
        "type": '0',
        "valid": '0',
        "note": "#隐藏#"
    }
    for item in place_set:
        place_list.append(item[0])
    if request.method == "GET":
        user_list_obj = models.object_info.objects.filter(
            data_status=0).order_by("name")
        warning_obj = []
        for obj in user_list_obj:
            if check_if_warning(obj.count, obj.valid_date, obj.note) == True:
                warning_obj.append(obj)
        return render(request, 'object_list.html', {
            'li': warning_obj,
            'pls': place_list,
            'slt': selected
        })


def add_object(request):
    if request.method == "GET":
        print("add_object:GET")
        obj = NewObjectForm()
        render(request, 'new_object.html', {"obj": obj})

    if request.method == 'POST':
        print("add_object:POST")
        obj = NewObjectForm(request.POST)
        name = request.POST['name']
        place = request.POST['place']
        type = request.POST['type']
        count = request.POST['count']
        unit = request.POST['unit']
        valid = request.POST['valid']
        spec_days = request.POST['spec_days']
        spec_weeks = request.POST['spec_weeks']
        spec_months = request.POST['spec_months']
        forever = request.POST.getlist('forever')
        note = request.POST['note']
        print(type, valid, spec_days, spec_weeks, spec_months, len(forever))
        if valid != '':
            valid_date = str2date(valid)
        elif spec_days != '':
            valid_date = timezone.now() + datetime.timedelta(
                days=1) * int(spec_days)
        elif spec_weeks != '':
            valid_date = timezone.now() + datetime.timedelta(
                days=7) * int(spec_weeks)
        elif spec_months != '':
            valid_date = timezone.now() + datetime.timedelta(
                days=30) * int(spec_months)
        elif len(forever) > 0:
            valid_date = '9999-12-31'

        models.object_info.objects.create(name=name,
                                          place=place,
                                          type=type,
                                          count=count,
                                          unit=unit,
                                          valid_date=valid_date,
                                          note=note)
        messages.success(request, "录入成功")

    return render(request, 'new_object.html', {'obj': obj})


def delete_object(request):
    nid = request.GET.get('nid')
    models.object_info.objects.filter(id=nid).update(data_status=1)
    return redirect('/all_objects')


def edit_object(request):
    if request.method == 'GET':
        nid = request.GET.get('nid')
        db_obj = models.object_info.objects.filter(id=nid).first()
        form_obj = NewObjectForm()
        form_obj.set_default(db_obj.name, db_obj.place, db_obj.type,
                             db_obj.count, db_obj.unit,
                             date2str(db_obj.valid_date), db_obj.note)
        return render(request, 'edit_object.html', {"obj": form_obj})

    if request.method == 'POST':
        nid = request.GET.get('nid')
        name = request.POST['name']
        place = request.POST['place']
        type = request.POST['type']
        count = request.POST['count']
        unit = request.POST['unit']
        valid = request.POST['valid']
        note = request.POST['note']
        models.object_info.objects.filter(id=nid).update(
            name=name,
            place=place,
            type=type,
            count=count,
            unit=unit,
            valid_date=str2date(valid),
            note=note)
        messages.success(request, "修改成功")
    return redirect('/all_objects')


def get_post_info():
    user_list_obj = models.object_info.objects.filter(
        data_status=0).order_by("name")
    res = ""
    count = 0
    for obj in user_list_obj:
        if check_if_warning(obj.count, obj.valid_date, obj.note) == True:
            res += str(count + 1) + '.' + obj.name + " 位置:" + obj.place + '\n'
            count += 1
    return count, res


def get_already_outdate():
    condtions = {"data_status": 0}
    condtions["valid_date__lt"] = timezone.now()
    user_list_obj = models.object_info.objects.filter(
        **condtions).order_by("valid_date")
    res = ""
    count = 0
    for obj in user_list_obj:
        res += str(count + 1) + '.' + obj.name + " 位置:" + obj.place + '\n'
        count += 1
    return count, res


def get_oneweek_outdate():
    condtions = {"data_status": 0}
    condtions["valid_date__gt"] = timezone.now()
    condtions["valid_date__lt"] = timezone.now() + datetime.timedelta(days=7)
    user_list_obj = models.object_info.objects.filter(
        **condtions).order_by("valid_date")
    res = ""
    count = 0
    for obj in user_list_obj:
        res += str(count + 1) + '.' + obj.name + " 位置:" + obj.place + '\n'
        count += 1
    return count, res


def get_warning_reason(str_note):
    res = str_note
    res.replace("告警", "")
    return res


def get_warning_obj():
    res = ""
    count = 0
    user_list_obj = models.object_info.objects.filter(
        data_status=0).order_by("name")
    warning_obj = []
    for obj in user_list_obj:
        if check_if_warning(obj.count, obj.valid_date, obj.note) == True:
            warning_obj.append(obj)
            res += str(
                count + 1
            ) + '.' + obj.name + " 位置:" + obj.place + " 告警原因:" + get_warning_reason(
                obj.note) + '\n'
            count += 1
    return count, res


def info_post(request):
    warn_ct, warn_str = get_warning_obj()
    warn_data = "告警物品 " + str(warn_ct) + " 个:\n" + warn_str
    al_ct, al_str = get_already_outdate()
    al_data = "\n已过期物品 " + str(al_ct) + " 个:\n" + al_str
    ow_ct, ow_str = get_oneweek_outdate()
    ow_data = "\n一周内过期物品 " + str(ow_ct) + " 个:\n" + ow_str
    wp.send_weixin(warn_data + al_data + ow_data)
    return HttpResponse('OK')
